/*-------------------------------------------------------------------------
 * output_plugin.h
 *	   PostgreSQL 逻辑解码插件接口
 *
 * Copyright (c) 2012-2022, PostgreSQL Global Development Group
 *
 *-------------------------------------------------------------------------
 */
#ifndef OUTPUT_PLUGIN_H
#define OUTPUT_PLUGIN_H

#include "replication/reorderbuffer.h"

struct LogicalDecodingContext;
struct OutputPluginCallbacks;

typedef enum OutputPluginOutputType
{
	OUTPUT_PLUGIN_BINARY_OUTPUT,
	OUTPUT_PLUGIN_TEXTUAL_OUTPUT
} OutputPluginOutputType;

/*
 * 在启动回调中由输出插件设置的选项。
 */
typedef struct OutputPluginOptions
{
	OutputPluginOutputType output_type;
	bool		receive_rewrites;
} OutputPluginOptions;

/*
 * 在加载输出插件共享库时查找的共享库符号 _PG_output_plugin_init 的类型。
 */
typedef void (*LogicalOutputPluginInit) (struct OutputPluginCallbacks *cb);

/*
 * 在用户定义的插件中调用的回调。ctx->private_data 可以
 * 设置为某些私有数据。
 *
 * 如果解码槽刚刚被定义，"is_init" 将被设置为 "true"。从此之后
 * 使用相同槽时，它将是 "false"。
 */
typedef void (*LogicalDecodeStartupCB) (struct LogicalDecodingContext *ctx,
										OutputPluginOptions *options,
										bool is_init);

/*
 * 每个成功事务的（显式或隐式）BEGIN 调用的回调。
 */
typedef void (*LogicalDecodeBeginCB) (struct LogicalDecodingContext *ctx,
									  ReorderBufferTXN *txn);

/*
 * 每个成功事务中的单个更改的回调。
 */
typedef void (*LogicalDecodeChangeCB) (struct LogicalDecodingContext *ctx,
									   ReorderBufferTXN *txn,
									   Relation relation,
									   ReorderBufferChange *change);

/*
 * 每个成功事务中的 TRUNCATE 的回调。
 */
typedef void (*LogicalDecodeTruncateCB) (struct LogicalDecodingContext *ctx,
										 ReorderBufferTXN *txn,
										 int nrelations,
										 Relation relations[],
										 ReorderBufferChange *change);

/*
 * 每个成功事务的（显式或隐式）COMMIT 调用的回调。
 */
typedef void (*LogicalDecodeCommitCB) (struct LogicalDecodingContext *ctx,
									   ReorderBufferTXN *txn,
									   XLogRecPtr commit_lsn);

/*
 * 对通用逻辑解码消息的调用。
 */
typedef void (*LogicalDecodeMessageCB) (struct LogicalDecodingContext *ctx,
										ReorderBufferTXN *txn,
										XLogRecPtr message_lsn,
										bool transactional,
										const char *prefix,
										Size message_size,
										const char *message);
#ifdef FDD
typedef bool (*FDB_WalSndKeepaliveCallback) (void);
#endif

/*
 * 按源过滤更改。
 */
typedef bool (*LogicalDecodeFilterByOriginCB) (struct LogicalDecodingContext *ctx,
											   RepOriginId origin_id);

/*
 * 调用以关闭输出插件。
 */
typedef void (*LogicalDecodeShutdownCB) (struct LogicalDecodingContext *ctx);

/*
 * 在解码 PREPARE 记录之前调用，以决定此
 * 事务是否应该使用单独的 prepare 和
 * commit_prepared/rollback_prepared 回调进行解码，或等到 COMMIT PREPARED
 * 并作为常规事务发送。
 */
typedef bool (*LogicalDecodeFilterPrepareCB) (struct LogicalDecodingContext *ctx,
											  TransactionId xid,
											  const char *gid);

/*
 * 每个准备事务的 BEGIN 调用的回调。
 */
typedef void (*LogicalDecodeBeginPrepareCB) (struct LogicalDecodingContext *ctx,
											 ReorderBufferTXN *txn);

/*
 * 调用 PREPARE 记录，除非它被 filter_prepare()
 * 回调过滤掉。
 */
typedef void (*LogicalDecodePrepareCB) (struct LogicalDecodingContext *ctx,
										ReorderBufferTXN *txn,
										XLogRecPtr prepare_lsn);

/*
 * 调用 COMMIT PREPARED。
 */
typedef void (*LogicalDecodeCommitPreparedCB) (struct LogicalDecodingContext *ctx,
											   ReorderBufferTXN *txn,
											   XLogRecPtr commit_lsn);

/*
 * 调用 ROLLBACK PREPARED。
 */
typedef void (*LogicalDecodeRollbackPreparedCB) (struct LogicalDecodingContext *ctx,
												 ReorderBufferTXN *txn,
												 XLogRecPtr prepare_end_lsn,
												 TimestampTz prepare_time);


/*
 * 当开始流式传输来自进行中的事务的更改块时调用
 * （如果分多次流式传输，则可能会重复调用）。
 */
typedef void (*LogicalDecodeStreamStartCB) (struct LogicalDecodingContext *ctx,
											ReorderBufferTXN *txn);

/*
 * 当停止将一个变更块从正在进行的事务流向远程节点时调用
 * （如果分多次流式传输，则可能会被重复调用）。
 */
typedef void (*LogicalDecodeStreamStopCB) (struct LogicalDecodingContext *ctx,
										   ReorderBufferTXN *txn);

/*
 * 用于丢弃从正在进行的事务流向远程节点的变更。
 */
typedef void (*LogicalDecodeStreamAbortCB) (struct LogicalDecodingContext *ctx,
											ReorderBufferTXN *txn,
											XLogRecPtr abort_lsn);

/*
 * 用于准备从正在进行的事务流向远程节点的变更。它作为
 * 两阶段提交的一部分被调用。
 */
typedef void (*LogicalDecodeStreamPrepareCB) (struct LogicalDecodingContext *ctx,
											  ReorderBufferTXN *txn,
											  XLogRecPtr prepare_lsn);

/*
 * 用于应用从正在进行的事务流向远程节点的变更。
 */
typedef void (*LogicalDecodeStreamCommitCB) (struct LogicalDecodingContext *ctx,
											 ReorderBufferTXN *txn,
											 XLogRecPtr commit_lsn);

/*
 * 用于从正在进行的事务流式传输单个变更的回调。
 */
typedef void (*LogicalDecodeStreamChangeCB) (struct LogicalDecodingContext *ctx,
											 ReorderBufferTXN *txn,
											 Relation relation,
											 ReorderBufferChange *change);

/*
 * 用于从正在进行的事务流式传输通用逻辑解码消息的回调。
 */
typedef void (*LogicalDecodeStreamMessageCB) (struct LogicalDecodingContext *ctx,
											  ReorderBufferTXN *txn,
											  XLogRecPtr message_lsn,
											  bool transactional,
											  const char *prefix,
											  Size message_size,
											  const char *message);

/*
 * 用于从正在进行的事务流式传输截断的回调。
 */
typedef void (*LogicalDecodeStreamTruncateCB) (struct LogicalDecodingContext *ctx,
											   ReorderBufferTXN *txn,
											   int nrelations,
											   Relation relations[],
											   ReorderBufferChange *change);

/*
 * 输出插件回调
 */
typedef struct OutputPluginCallbacks
{
	LogicalDecodeStartupCB startup_cb;
	LogicalDecodeBeginCB begin_cb;
	LogicalDecodeChangeCB change_cb;
	LogicalDecodeTruncateCB truncate_cb;
	LogicalDecodeCommitCB commit_cb;
	LogicalDecodeMessageCB message_cb;
	LogicalDecodeFilterByOriginCB filter_by_origin_cb;
	LogicalDecodeShutdownCB shutdown_cb;

	/* 在准备时的变更流式传输 */
	LogicalDecodeFilterPrepareCB filter_prepare_cb;
	LogicalDecodeBeginPrepareCB begin_prepare_cb;
	LogicalDecodePrepareCB prepare_cb;
	LogicalDecodeCommitPreparedCB commit_prepared_cb;
	LogicalDecodeRollbackPreparedCB rollback_prepared_cb;

	/* 变更的流式传输 */
	LogicalDecodeStreamStartCB stream_start_cb;
	LogicalDecodeStreamStopCB stream_stop_cb;
	LogicalDecodeStreamAbortCB stream_abort_cb;
	LogicalDecodeStreamPrepareCB stream_prepare_cb;
	LogicalDecodeStreamCommitCB stream_commit_cb;
	LogicalDecodeStreamChangeCB stream_change_cb;
	LogicalDecodeStreamMessageCB stream_message_cb;
	LogicalDecodeStreamTruncateCB stream_truncate_cb;
} OutputPluginCallbacks;

/* replication/logical/logical.c 中的函数 */
extern void OutputPluginPrepareWrite(struct LogicalDecodingContext *ctx, bool last_write);
extern void OutputPluginWrite(struct LogicalDecodingContext *ctx, bool last_write);
extern void OutputPluginUpdateProgress(struct LogicalDecodingContext *ctx, bool skipped_xact);

#endif							/* OUTPUT_PLUGIN_H */
